package xyz.archknight.app.loginput.dictionary.gen.service

import org.jetbrains.exposed.sql.transactions.transaction
import xyz.archknight.app.loginput.dictionary.gen.bean.DatabaseProtocol
import xyz.archknight.app.loginput.dictionary.gen.bean.RecordItem
import xyz.archknight.app.loginput.dictionary.gen.bean.StatusProtocol
import xyz.archknight.app.loginput.dictionary.gen.dao.Cache
import xyz.archknight.app.loginput.dictionary.gen.dao.DBUtils
import xyz.archknight.app.loginput.dictionary.gen.dao.Word
import java.io.BufferedInputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream

/**
 * 内存数据库转储工具
 *
 * @author midnite
 * create at 2020-06-20 7:17 上午
 */
fun saveDatabaseToFile(file: String) {
    val filePath = if (file.endsWith(".akdb")) {
        file
    } else {
        "$file.akdb"
    }
    FileOutputStream(filePath).use { fos ->
        transaction {
            fos.write(serialize(mapOf(
                "main" to Word.all().toList().map {
                    RecordItem(it.phase, it.pinyin, it.id.value)
                },
                "cache" to Cache.all().toList().map {
                    RecordItem(it.phase, it.pinyin, it.id.value)
                }
            )))
        }
    }
}

fun loadDatabaseFromFile(file: File) {
    BufferedInputStream(FileInputStream(file)).use { bis ->
        val storageContent: Map<String, List<RecordItem>> = unserialize(bis.readBytes())
        if (storageContent.containsKey("main") &&
            storageContent.containsKey
            ("cache")) {
            DBUtils.resetTables()
            transaction {
                EventBus.refreshStatus(StatusProtocol.Loading, 0)
                storageContent["main"]?.let { words ->
                    words.sortedBy { it.seq }
                        .forEach { word ->
                            Word.new {
                                phase = word.phase
                                pinyin = word.pinyin
                            }
                        }
                }
                storageContent["cache"]?.let { words ->
                    words.sortedBy { it.seq }
                        .forEach { word ->
                            Cache.new {
                                phase = word.phase
                                pinyin = word.pinyin
                            }
                        }
                }
            }
            EventBus.dbChange(DatabaseProtocol.RefreshBoth)
        } else {
            throw IllegalArgumentException()
        }
    }
}